iT邦幫忙

2025 iThome 鐵人賽

DAY 24
1
自我挑戰組

用 C++ 實作簡易第一人稱視角遊戲:從入門到理解 Ray Casting系列 第 24

Day 24 | Ray Casting 中場總結:從光線到角色的移動

  • 分享至 

  • xImage
  •  

大家好,這裡是鐵匠史密斯~
時間過得真快,不知不覺我們已經來到鐵人賽的第 24 天!
昨天角色的前進與後退剛完成,今天就讓我們停下來小小喘口氣,
來回顧一下 Day 11 ~ Day 23 的進度,也順便整理一下目前遊戲的樣貌

1. 光線的基礎 (Day 11 ~ Day 14)

這段時間,我們從「第一道光」開始推導,逐步掌握了光線的行進方式:

  • 發射光線:透過 fRayAngle,決定每條光線的角度
  • 光線如何前進:利用 fDistanceToWall 模擬光一步一步往前走
  • 邊界情況:光跑出地圖會看見一堵「無形的牆」
    https://ithelp.ithome.com.tw/upload/images/20250824/20157653X7bGWQk254.png

2. 距離決定牆壁高度 (Day 15 ~ Day 17)

接著,我們讓「距離」影響到「牆壁在畫面上的高度」。
這裡的核心公式就是:

int nCeiling = (float)(nScreenHeight / 2.0) - nScreenHeight / ((float)fDistanceToWall);
int nFloor   = (float)(nScreenHeight / 2.0) + nScreenHeight / ((float)fDistanceToWall);

結果很直觀:
越近的牆 -> fDistanceToWall 越小 → 牆壁越高
越遠的牆 -> fDistanceToWall 越大 → 牆壁越矮
這段推導特地借用了光學的 針孔成像定理 來解釋,
牆壁就像物體,螢幕就像底片(人眼視網膜),
所以牆高與距離成反比 H = h * 1 / d ~ 1/d

3. 角色操控與牆面渲染 (Day 18 ~ Day 23)

光線與牆高確立之後,我們開始開發玩家的移動功能。
玩家轉動 (Q / E):用 fPlayerA 控制角色方向,並搭配 chrono 套件,讓旋轉速率不受硬體 FPS 限制
玩家移動 (W / S):透過 x = sinf(fPlayerA)y = cosf(fPlayerA) 結合的單位向量,模擬角色向前走 / 後退
牆面渲染:不只是 #,利用 short int 裝載16進位數字,裝載 ░▒▓█ 這些「漸層字元」,
讓遠近的牆有深淺之分,畫面更有立體感
到這裡,遊戲從一開始的「黑白畫布」,進化成一個能走能轉、還有陰影的「類 3D 世界」。

4. 目前的遊戲樣貌

直接放一張 Demo 圖會很有感,角色站在 (8, 3),能轉動、能移動,
看到的牆會隨著遠近而變高、變暗:
https://ithelp.ithome.com.tw/upload/images/20250824/20157653ChukyaHVWS.png

「到目前為止,我們已經從單純的 wchar_t* screen,發展成一個能探索迷宮的『類 3D 第一人稱遊戲』了!」

5. 下一步展望

雖然目前的成果已經讓人小小感動,但我們還沒完工:
還需要優化 邊界處理,我們要真正地避免玩家走出世界的盡頭
以及處理地板的渲染

今日總結

  • 統整 Day11 ~ Day23 的進度:從光線 → 牆高 → 玩家操控 → 陰影渲染
  • 現在的遊戲:已經能看、能轉、能走,畫面也有了遠近感

寫到第 24 天,其實每天都有新的「坑」出現,
一開始覺得是數學難、後來覺得是程式難,
但慢慢拆解後,卻越來越覺得好玩。
所以~還有很多東西要一起走下去~


上一篇
Day 23 | 角色的前進與後退
下一篇
Day 25 | Ray Casting 渲染地板 - Part 1
系列文
用 C++ 實作簡易第一人稱視角遊戲:從入門到理解 Ray Casting30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言